/**
 * @widoc $.fn.initCarousel
 * @namespace comp
 * @des 为元素 el 中的多屏内容，创建轮播。el 中只允许包含一个元素，该元素的每个直接子元素对应一屏内容。
 * @type function
 * @demo initCarousel/demo0 轮播屏
 * @param {object} opts 配置参数
 * @param {boolean=} opts.autoplay 是否允许自动播放，默认为 true。
 * @param {string=} opts.animateType 切换效果。可选效果：'slide','slideV','fade'，默认为 无效果。
 * @param {number=} opts.duration 切换动画持续时间，单位 ms（animateType 未定义时失效）。
 * @param {number=} opts.delay 轮播间隔时间，单位 ms。
 * @param {number=} opts.num 初始化时显示的第一屏索引，从 0 开始，默认为 0。
 * @param {boolean=} opts.showNav 是否显示导航，默认为 true。
 * @param {function=} opts.fNavItemRender 导航项自定义渲染函数，function(i)。
 *   - {number} i 绘制导航的屏索引。
 * @param {boolean=} opts.showArrow 是否显示左右箭头，默认为 true。
 * @param {function=} opts.fItemCb <span class="t_gray80">请用 opts.afterGoto 替代。</span>
 * @param {function=} opts.beforeGoto 切换前的回调事件，function(newIdx, oldIdx)。
 *   - {number} newIdx 切换后的屏索引。
 *   - {number} oldIdx 切换前的屏索引。
 * @param {function=} opts.afterGoto 切换后的回调事件，function(newIdx, oldIdx)。
 *   - {number} newIdx 切换后的屏索引。
 *   - {number} oldIdx 切换前的屏索引。
 * @return {object|undefined} obj 接口对象
 * @rtn {function} obj.fReset(cusOpts) 重置
 *   - cusOpts {object} 参见初始化参数 opts
 * @rtn {function} obj.fStartCarousel() 开始轮播
 * @rtn {function} obj.fStopCarousel() 停止轮播
 * @rtn {function} obj.fGoto(i,triggerCb) 切换到指定屏
 *   - i {number} 要切换的屏索引
 *   - triggerCb {boolean=} 是否触发用户回调，默认为 false
 */
$.fn.initCarousel = function(opts){
    var el = $(this),// el 中只允许包含一个元素，该元素的每个直接子元素对应一屏内容
        api;
    opts = $.extend({
        autoplay: true,// 是否允许自动播放
        //animateType: undefined,// 切换效果：'slide','slideV','fade'
        duration: 1000,// 切换动画持续时间，单位 ms（animateType 未定义时失效）
        delay: 5000,// 轮播间隔时间，单位 ms
        num: 0, // 初始化时显示的第一屏索引，从 0 开始
        showNav: true,// 是否显示导航
        //fNavItemRender: function(i)// 导航项自定义渲染函数
        showArrow: true,// 是否显示左右箭头
        beforeGoto: $.noop,// 切换前的回调事件 function(oldIdx, newIdx)
        afterGoto: $.noop// 切换后的回调事件 function(oldIdx, newIdx)
        //fItemCb: $.noop// TODO del 兼容旧版本，现改为 afterGoto
    }, opts);
    var jqMain,// 屏内容的主容器
        jqsCont,// 所有屏内容元素集合
        jqNav;// 切换导航容器元素
    var nCount;// 滚动屏数
    var curIdx;// 当前屏索引，切换前的屏索引
    var oTimer = null,// 自动切换定时器
        bAutoplay,// 记录当前是否自动轮播
        sAnimateType;// 记录切换效果
    // 自动播放
    var fStartCarousel = function(){
        if(nCount > 1){
            bAutoplay = true;
            if(!oTimer){
                oTimer = setTimeout(function(){
                    oTimer = null;
                    fGoto(curIdx + 1, true);
                }, opts.delay);
            }
        }
    };
    // 停止自动播放
    var fStopCarousel = function(){
        bAutoplay = false;
        if(oTimer){
            clearTimeout(oTimer);
            oTimer = null;
        }
    };
    // 左右箭头点击事件
    var fCtrlClick = function(){
        var type = $(this).attr('data-type');
        fGoto(type == 'prev' ? curIdx - 1 : curIdx + 1, true);
    };
    // 导航点击事件
    var fNavClick = function(){
        fGoto($(this).index(), true);
    };
    // 滚到 newIdx 指定的屏
    var fGoto = function(newIdx, triggerCb){
        var jqCurCont, jqNewCont,// 切换显示前/后的屏内容元素
            flag;// 切换方向，1 从右向左，-1 从左向右
        var duration = opts.duration;// 动画持续时间
        var oldIdx = curIdx;
        // 切换完成后的回调方法
        var fAfterGoto = function(){
            if(bAutoplay){ //如果是自动播放的，需要主动调用autoPlay()函数
                fStartCarousel();
            }
            jqNav && jqNav.find('li').removeClass('active')
                          .eq(curIdx).addClass('active');
            triggerCb && opts.afterGoto(newIdx, oldIdx);// 用户自定义回调事件
        };
        if(sAnimateType){// 切换效果启用时，开始下一次切换前，需先结束正在进行的切换
            var jqsAnimating = jqsCont.filter(':animated');
            if(jqsAnimating.length){
                jqsAnimating.finish();
            }
        }
        if(newIdx === oldIdx){
            return;
        }
        if(oldIdx < newIdx){// 从右向左滑动，newIdx 屏先移到右侧
            flag = 1;
        }
        else{
            flag = -1;
        }
        if(newIdx >= nCount){// 如果下一个要运动的索引值超过最大索引，就回到第一个
            newIdx = 0;
        }
        else if(newIdx < 0){// 如果下一个要运动的索引值小于最小索引，就回到第最后一个
            newIdx = nCount - 1;
        }
        jqNewCont = jqsCont.eq(newIdx);
        if(oldIdx === -1){// 第一次显示，不需要动画
            triggerCb && opts.beforeGoto(newIdx, oldIdx);
            curIdx = newIdx;
            if(sAnimateType == 'slide'){
                jqNewCont.css('left', 0);
            }
            else if(sAnimateType == 'slideV'){
                jqNewCont.css({
                    display: '',
                    top: 0,
                    bottom: 'auto'
                });
            }
            else if(sAnimateType == 'fade'){
                jqNewCont.css('display', '');
            }
            else{
                jqNewCont.css('display', '');
            }
            fAfterGoto();
        }
        else{
            jqCurCont = jqsCont.eq(oldIdx);
            triggerCb && opts.beforeGoto(newIdx, oldIdx);
            curIdx = newIdx;
            if(sAnimateType == 'slide'){
                jqNewCont.css('left', flag + '00%'); //将即将进入视图的元素定位到右侧或左侧
                jqNewCont.animate({
                    left: 0
                }, duration, fAfterGoto);
                jqCurCont.animate({
                    left: -flag + '00%'
                }, duration); //将之前展示的元素移出当前区域
            }
            else if(sAnimateType == 'slideV'){
                if(flag == 1){
                    jqCurCont.css({
                        top: 0,
                        bottom: 'auto'
                    });
                    jqNewCont.css({
                        top: 'auto',
                        bottom: 0
                    });
                }
                else{
                    jqCurCont.css({
                        top: 'auto',
                        bottom: 0
                    });
                    jqNewCont.css({
                        top: 0,
                        bottom: 'auto'
                    });
                }
                jqNewCont.slideDown(duration, fAfterGoto);
                jqCurCont.slideUp(duration); //将之前展示的元素移出当前区域
            }
            else if(sAnimateType == 'fade'){
                jqNewCont.fadeIn(duration, fAfterGoto);
                jqCurCont.fadeOut(duration); //将之前展示的元素移出当前区域
            }
            else{
                jqNewCont.css('display', '');
                jqCurCont.css('display', 'none');
                fAfterGoto();
            }
        }
    };

    // 绘制导航
    var fDrawNav = function(){
        if(!jqNav){
            return;
        }
        var str = '',
            fNavItemRender = opts.fNavItemRender;
        for(var i = 0; i < nCount; i++){
            str += '<li class="wi-carousel-nav-item">' +
                (fNavItemRender ? fNavItemRender(i) : '') +
                '</li>';
        }
        jqNav.html(str);
    };
    var fReset = function(cusOpts){
        $.extend(opts, cusOpts);
        var showNav = opts.showNav,
            showArrow = opts.showArrow;
        jqsCont = jqMain.children();
        jqsCont.addClass('wi-carousel-item');// 所有屏内容元素
        nCount = jqsCont.length;// 屏数
        sAnimateType = opts.animateType;
        curIdx = -1;// 屏数可能发生变化，重新计数
        bAutoplay = false;
        // 是否显示导航
        if(nCount < 2 || showNav === false){// 隐藏 navbar
            jqNav.css('display', 'none'); // 隐藏导航栏
        }
        else{
            fDrawNav();// 根据屏数绘制导航
            jqNav && jqNav.css('display', '');
        }
        // 是否显示切换箭头
        if(nCount < 2 || showArrow === false){
            el.find('.wi-carousel-ctrl').css('display', 'none');
        }
        else{
            el.find('.wi-carousel-ctrl').css('display', '');
        }
        // 多屏内容初始化
        if(nCount > 1){
            // 允许自动播放
            if(opts.autoplay){
                bAutoplay = true;
            }
            if(sAnimateType == 'slide'){
                jqsCont.css('left', '100%');// 全部内容移出视图
            }
            else if(sAnimateType == 'slideV'){
                jqsCont.css({
                    display: 'none',
                    top: 'auto',
                    bottom: 0
                });// 全部内容移出视图
            }
            else if(sAnimateType == 'fade'){
                jqsCont.css('display', 'none');// 全部内容隐藏
            }
            else{
                jqsCont.css('display', 'none');// 全部内容隐藏
            }
        }
        fGoto(opts.num, true);
    };
    var fInit = function(){
        el.addClass('wi-carousel');
        el.css('position') == 'static' && el.css('position', 'relative');// 设置为定位元素
        jqMain = el.children().eq(0);
        jqMain.addClass('wi-carousel-main');
        /* el 子元素处理 */
        (function(){
            el.children('.wi-carousel-ctrl,.wi-carousel-nav').remove();
            // 导航
            jqNav = $('<ul class="wi-carousel-nav"></ul>');// 导航容器
            el.append(jqNav);
            // 箭头
            el.append('<div class="wi-carousel-ctrl wi-carousel-ctrl-prev" data-type="prev">' +
                '<span class="wi-carousel-arrow"></span></div>' +
                '<div class="wi-carousel-ctrl wi-carousel-ctrl-next" data-type="next">' +
                '<span class="wi-carousel-arrow"></span></div>');
        })();
        el.off('click.carouselNav click.carouselCtrl mouseenter.carousel mouseleave.carousel')
          .on('click.carouselNav', '.wi-carousel-nav-item', fNavClick)// 导航点击事件
          .on('click.carouselCtrl', '.wi-carousel-ctrl', fCtrlClick)// 左右箭头点击事件
          .on('mouseenter.carousel', fStopCarousel)// 移入停止定时器
          .on('mouseleave.carousel', fStartCarousel);// 移出开启定时器
        fReset();
    };
    api = {
        fReset: fReset,
        fStartCarousel: fStartCarousel,// 开始轮播
        fStopCarousel: fStopCarousel,// 停止轮播
        fGoto: fGoto// 切换到指定屏
    };
    fInit();
    return api;
};